using System;
using System.Collections.Generic;
using System.Globalization;
using System.Xml;
using MEA.AE_Data;
using MEA.AE_Data.Config;

namespace MEA.AE_BusinessLogic
{
	public class XmlLogFlashContainer : Xml_Log
	{
		private int CntOfBlocks;

		public string XMLWizardScript;

		public string XMLWizardPostScript;

		private void FlashCANParameterRead(XmlReader reader)
		{
			ushort num = 0;
			ushort num2 = 0;
			string text = "";
			while (reader.ReadToFollowing("CAN_IDENTIFIER"))
			{
				text = (string)ReadGenericValue(reader, "CAN_DEVICE");
				num = Convert.ToUInt16(ReadGenericValue(reader, "CAN_DEVICE_TARGET").ToString().PadLeft(2), 16);
				num2 = Convert.ToUInt16(ReadGenericValue(reader, "CAN_DEVICE_REPLY").ToString().PadLeft(2), 16);
				if (text == "ECU-A")
				{
					ConfigKWP.CanMsgIDs_Set(ConfigData.e_ECUID.A, num2, num);
				}
				else if (text == "ECU-B")
				{
					ConfigKWP.CanMsgIDs_Set(ConfigData.e_ECUID.B, num2, num);
				}
			}
		}

		private void FlashKWPParameterRead(XmlReader reader)
		{
			if (!reader.ReadToFollowing("KWP2000_TIMING"))
			{
				throw new Exception("Internal: no KWP2000_TIMING in file");
			}
			XmlReader xmlReader = reader.ReadSubtree();
			while (xmlReader.ReadToFollowing("KWP_SEQUENCE"))
			{
				string text = "";
				byte b = 0;
				byte b2 = 0;
				byte b3 = 0;
				byte b4 = 0;
				byte b5 = 0;
				text = (string)ReadGenericValue(xmlReader, "KWP_SEQUENCE_ID");
				b = Convert.ToByte(ReadGenericValue(xmlReader, "KWP_P2MIN").ToString().PadLeft(2), 16);
				b2 = Convert.ToByte(ReadGenericValue(xmlReader, "KWP_P2MAX").ToString().PadLeft(2), 16);
				b3 = Convert.ToByte(ReadGenericValue(xmlReader, "KWP_P3MIN").ToString().PadLeft(2), 16);
				b4 = Convert.ToByte(ReadGenericValue(xmlReader, "KWP_P3MAX").ToString().PadLeft(2), 16);
				b5 = Convert.ToByte(ReadGenericValue(xmlReader, "KWP_P4MIN").ToString().PadLeft(2), 16);
				if (text == "ERASE")
				{
					ConfigFlash.TimingParameterSet(ConfigFlash.e_timingParameter.eraseFlash, new List<byte>(new byte[5] { b, b2, b3, b4, b5 }));
				}
				else if (text == "PROGRAM")
				{
					ConfigFlash.TimingParameterSet(ConfigFlash.e_timingParameter.writeFlash, new List<byte>(new byte[5] { b, b2, b3, b4, b5 }));
				}
			}
			if (!reader.ReadToFollowing("KWP2000_ACCESS"))
			{
				throw new Exception("Internal: no KWP2000_ACCESS in file");
			}
			xmlReader = reader.ReadSubtree();
			while (xmlReader.ReadToFollowing("KWP_SECACC"))
			{
				string text2 = "";
				byte b6 = 0;
				text2 = (string)ReadGenericValue(xmlReader, "KWP_SECACC_ID");
				b6 = Convert.ToByte(ReadGenericValue(xmlReader, "KWP_DIAG_MODE").ToString().PadLeft(2), 16);
				if (text2 == "FLASH")
				{
					ConfigKWP.DiagMode_Set(ConfigKWP.e_DiagModes.Flash, b6);
				}
				else if (text2 == "DIAG")
				{
					ConfigKWP.DiagMode_Set(ConfigKWP.e_DiagModes.Diagnostic, b6);
				}
			}
		}

		private void FlashConditionsRead(XmlReader reader, ref FlashContainer fctA, ref FlashContainer fctB)
		{
			fctA = new FlashContainer();
			fctB = new FlashContainer();
			FlashContainer.XMLFlashConditions conditions = default(FlashContainer.XMLFlashConditions);
			FlashBlock.XMLFlashBlock fb = default(FlashBlock.XMLFlashBlock);
			bool flag = true;
			FlashBlock flashBlock = new FlashBlock();
			NumberFormatInfo numberFormatInfo = new NumberFormatInfo();
			numberFormatInfo.NumberDecimalSeparator = ".";
			while (reader.Read() && flag)
			{
				switch (reader.NodeType)
				{
				case XmlNodeType.Element:
					switch (reader.Name)
					{
					case "FILE_FCT_VERSION":
					{
						string text2 = reader.ReadElementContentAsString();
						if (text2.StartsWith("V"))
						{
							text2 = text2.Substring(1, text2.Length - 1);
							conditions.file_fct_version = Convert.ToSingle(text2, numberFormatInfo);
						}
						break;
					}
					case "FLASH_SW_VERSION":
						conditions.conditions_sw_v = reader.ReadString();
						break;
					case "FLASH_DS_VERSION":
						conditions.conditions_ds_v = reader.ReadElementContentAsInt();
						break;
					case "FLASH_HW_VERSION":
						conditions.conditions_hw_v = reader.ReadElementContentAsInt();
						break;
					case "FLASH_ENGINE_TYPE":
						conditions.conditions_engType = reader.ReadElementContentAsString();
						break;
					case "FLASH_WIZARD_MIN":
						conditions.conditions_wizard_min = reader.ReadElementContentAsString();
						break;
					case "FLASH_WIZARD_MAX":
						conditions.conditions_wizard_max = reader.ReadElementContentAsString();
						break;
					case "FLASH_ECU-SW_MIN":
						conditions.conditions_ecu_sw_min = reader.ReadElementContentAsString();
						break;
					case "FLASH_ECU-SW_MAX":
						conditions.conditions_ecu_sw_max = reader.ReadElementContentAsString();
						break;
					case "FLASH_ECU-DS_MIN":
						conditions.conditions_ecu_ds_min = reader.ReadElementContentAsInt();
						break;
					case "FLASH_ECU-DS_MAX":
						conditions.conditions_ecu_ds_max = reader.ReadElementContentAsInt();
						break;
					case "FLASH_ECU-HW_MIN":
						conditions.conditions_ecu_hw_min = reader.ReadElementContentAsInt();
						break;
					case "FLASH_ECU-HW_MAX":
						conditions.conditions_ecu_hw_max = reader.ReadElementContentAsInt();
						break;
					case "FLASH_BUS_VOLTS_MIN":
						conditions.conditions_bus_volts_min = reader.ReadElementContentAsFloat();
						break;
					case "FLASH_IGNORE_COND":
						conditions.conditions_ignore = reader.ReadElementContentAsBoolean();
						break;
					case "ENGINESERIAL_SERIALNR_MIN":
						conditions.min_serial_motor_nr = reader.ReadElementContentAsString();
						break;
					case "ENGINESERIAL_SERIALNR_MAX":
						conditions.max_serial_motor_nr = reader.ReadElementContentAsString();
						break;
					case "FLASH_BLOCK_LINK":
					{
						string text = reader["blType"];
						if (text != null && text != string.Empty)
						{
							fb.fdType = flashBlock.mkFDType(text);
						}
						else
						{
							fb.fdType = FlashBlock.EFD_Types.eFD_NoEFD_Type;
						}
						break;
					}
					case "FLASH_BLOCK_TOTAL_NUMBER":
						CntOfBlocks = reader.ReadElementContentAsInt();
						break;
					case "FLASH_BLOCK_ID":
						fb.id = (uint)reader.ReadElementContentAsInt();
						break;
					case "FLASH_BLOCK_NAME":
						fb.name = reader.ReadElementContentAsString();
						break;
					case "FLASH_BLOCK_PROGRAMMABLE":
						fb.blockProgrammable = reader.ReadElementContentAsBoolean();
						break;
					case "FLASH_BLOCK_CNT":
						fb.nrOfBlocks = reader.ReadElementContentAsInt();
						break;
					case "FLASH_BLOCK_ERASEABLE":
						fb.blockEraseable = reader.ReadElementContentAsBoolean();
						break;
					case "FLASH_BLOCK_ERASE_START":
						fb.eraseStartAdr = (uint)Convert.ToInt32(reader.ReadElementContentAsString().Remove(0, 2), 16);
						break;
					case "FLASH_BLOCK_ERASE_END":
						fb.eraseEndAdr = (uint)Convert.ToInt32(reader.ReadElementContentAsString().Remove(0, 2), 16);
						break;
					case "FLASH_BLOCK_CHECKABLE":
						fb.blockCheckable = reader.ReadElementContentAsBoolean();
						break;
					case "FLASH_BLOCK_CHECK_START_ADDR":
						fb.chksumStartAdr = (uint)Convert.ToInt32(reader.ReadElementContentAsString().Remove(0, 2), 16);
						break;
					case "FLASH_BLOCK_CHECK_END_ADDR":
						fb.chksumEndAdr = (uint)Convert.ToInt32(reader.ReadElementContentAsString().Remove(0, 2), 16);
						break;
					case "FLASH_BLOCK_CHECK_SUM":
						fb.checkSum = (uint)Convert.ToInt32(reader.ReadElementContentAsString().Remove(0, 2), 16);
						break;
					}
					break;
				case XmlNodeType.EndElement:
					switch (reader.Name)
					{
					case "FLASH_CONDITIONS":
						fctA.addToFlashContainer(ref conditions);
						fctB.addToFlashContainer(ref conditions);
						break;
					case "FLASH_BLOCK_LINK":
						fctA.AddFlashblock(new FlashBlock(ref fb));
						fctB.AddFlashblock(new FlashBlock(ref fb));
						break;
					case "FCT_HEADER":
						if (CntOfBlocks != fctA.FlashBlockAreas.Count)
						{
							fctA = null;
							fctB = null;
							throw new Exception("Internal: Count of Flash areas is wrong");
						}
						flag = false;
						break;
					}
					break;
				}
			}
		}

		private void FlashDataRead(XmlReader flashBlockDataReader, ref FlashContainer fcontainerA, ref FlashContainer fcontainerB)
		{
			FlashBlockData.XMLFlashData data = default(FlashBlockData.XMLFlashData);
			bool flag = true;
			new List<byte>();
			int num = 8384;
			data.length = 0u;
			FlashBlock flashBlock = new FlashBlock();
			while (flag && flashBlockDataReader.Read())
			{
				switch (flashBlockDataReader.NodeType)
				{
				case XmlNodeType.Element:
					switch (flashBlockDataReader.Name)
					{
					case "FD_BLOCK_ID":
						data.id = (uint)flashBlockDataReader.ReadElementContentAsInt();
						break;
					case "FD_BLOCK_NUM":
						data.number = (uint)flashBlockDataReader.ReadElementContentAsInt();
						break;
					case "FD_START_ADDR":
						data.startAdr = Convert.ToUInt32(flashBlockDataReader.ReadElementContentAsString().Remove(0, 2), 16);
						break;
					case "FD_SIZE":
						data.length = Convert.ToUInt32(flashBlockDataReader.ReadElementContentAsString().Remove(0, 2), 16);
						break;
					case "FD_ERASE_START":
						data.eraseStartAdr = Convert.ToUInt32(flashBlockDataReader.ReadElementContentAsString().Remove(0, 2), 16);
						break;
					case "FD_ERASE_END":
						data.eraseEndAdr = Convert.ToUInt32(flashBlockDataReader.ReadElementContentAsString().Remove(0, 2), 16);
						break;
					case "FD_CHECKABLE":
						data.blockCheckable = flashBlockDataReader.ReadElementContentAsBoolean();
						break;
					case "FD_CHECK_START_ADDR":
						data.chksumStartAdr = Convert.ToUInt32(flashBlockDataReader.ReadElementContentAsString().Remove(0, 2), 16);
						break;
					case "FD_CHECK_END_ADDR":
						data.chksumEndAdr = Convert.ToUInt32(flashBlockDataReader.ReadElementContentAsString().Remove(0, 2), 16);
						break;
					case "FD_CHECK_SUM":
						data.checkSum = Convert.ToUInt32(flashBlockDataReader.ReadElementContentAsString().Remove(0, 2), 16);
						break;
					case "FD_BLOCK_DATA":
						flashBlockDataReader.Read();
						num = flashBlockDataReader.Value.Length;
						data.buf = new byte[num];
						flashBlockDataReader.ReadContentAsBase64(data.buf, 0, num);
						break;
					case "EXFD_BLOCK":
					{
						string text = flashBlockDataReader["blType"];
						if (text != null && text != string.Empty)
						{
							data.fdType = flashBlock.mkFDType(text);
						}
						else
						{
							data.fdType = FlashBlock.EFD_Types.eFD_NoEFD_Type;
						}
						break;
					}
					}
					break;
				case XmlNodeType.EndElement:
					switch (flashBlockDataReader.Name)
					{
					case "FD_BLOCK":
						fcontainerA.AddFlashDataBlock(new FlashBlockData(ref data, true));
						fcontainerB.AddFlashDataBlock(new FlashBlockData(ref data, true));
						break;
					case "FLASH_DATA":
						flag = false;
						break;
					}
					break;
				}
			}
		}

		public bool FlashReadWizardScript(XmlReader reader)
		{
			bool result = false;
			reader.Read();
			reader.ReadToFollowing("FLASH_ADDON");
			if (reader.Name == "FLASH_ADDON")
			{
				XMLWizardScript = reader.ReadElementContentAsString();
				result = true;
			}
			reader.ReadToFollowing("FLASH_POST_ADDON");
			if (reader.Name == "FLASH_POST_ADDON")
			{
				XMLWizardPostScript = reader.ReadElementContentAsString();
				result = true;
			}
			return result;
		}

		public void ReadFlashContainer(XmlReader reader, ref FlashContainer fctA, ref FlashContainer fctB)
		{
			if (!reader.ReadToFollowing("FLASH_CONTAINER"))
			{
				throw new Exception("Internal: no FLASH_CONTAINER in file");
			}
			if (!reader.ReadToFollowing("FCT_HEADER"))
			{
				throw new Exception("Internal: no FLASH_CONTAINER in file");
			}
			FlashConditionsRead(reader, ref fctA, ref fctB);
			if (!reader.ReadToFollowing("FCT_BODY"))
			{
				throw new Exception("Internal: no FCT_BODY in file");
			}
			if (!reader.ReadToFollowing("CAN_PARAMETERS"))
			{
				throw new Exception("Internal: no CAN_PARAMETERS in file");
			}
			FlashCANParameterRead(reader.ReadSubtree());
			if (!reader.ReadToFollowing("KWP2000_PARAMETERS"))
			{
				throw new Exception("Internal: no KWP2000_PARAMETERS in file");
			}
			FlashKWPParameterRead(reader.ReadSubtree());
			if (!reader.ReadToFollowing("FLASH_DATA"))
			{
				throw new Exception("Internal: no FLASH_DATA in file");
			}
			FlashDataRead(reader.ReadSubtree(), ref fctA, ref fctB);
			reader.ReadToFollowing("FORM1_DATA");
			reader.ReadToFollowing("FCT_FOOTER");
			if (reader.ReadToFollowing("WIZARD_SCRIPTS"))
			{
				FlashReadWizardScript(reader);
			}
			reader.Close();
		}
	}
}
